import os
import shutil
import subprocess
import time
import sys
import io
import requests
import threading

# 强制标准输出使用 UTF-8 编码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# 下载线程数（可以调大，比如 8 或 16）
THREAD_COUNT = 8
# 最大重试次数
MAX_RETRIES = 5

# 检查 Java 环境
def check_java():
    try:
        result = subprocess.run(['java', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return result.returncode == 0
    except FileNotFoundError:
        return False

# 读取下载链接
def get_download_link():
    download_file = os.path.join(current_directory, "download.txt")
    if os.path.exists(download_file):
        with open(download_file, "r", encoding="utf-8") as file:
            content = file.read().strip()
            if '"' in content:
                return content.split('"')[1]
    return None

# 分块下载的工作线程
def download_chunk(url, start, end, part_num, temp_folder):
    headers = {"Range": f"bytes={start}-{end}"}
    retries = 0
    while retries < MAX_RETRIES:
        try:
            response = requests.get(url, headers=headers, stream=True, timeout=30)
            chunk_path = os.path.join(temp_folder, f"part_{part_num}")
            with open(chunk_path, "wb") as file:
                for chunk in response.iter_content(chunk_size=1024):
                    if chunk:
                        file.write(chunk)
            return True
        except Exception as e:
            print(f"\n分块 {part_num} 下载失败: {e}，正在重试 ({retries+1}/{MAX_RETRIES}) ...")
            retries += 1
            time.sleep(3)
    return False

# 多线程加速下载
def download_server_jar(url, save_path):
    response = requests.head(url)
    if "content-length" not in response.headers:
        print("无法获取文件大小，改用单线程下载...")
        return single_thread_download(url, save_path)

    total_size = int(response.headers["content-length"])
    chunk_size = total_size // THREAD_COUNT
    temp_folder = os.path.join(current_directory, "temp_parts")

    if not os.path.exists(temp_folder):
        os.makedirs(temp_folder)

    threads = []
    for i in range(THREAD_COUNT):
        start = i * chunk_size
        end = (i + 1) * chunk_size - 1 if i < THREAD_COUNT - 1 else total_size - 1
        thread = threading.Thread(target=download_chunk, args=(url, start, end, i, temp_folder))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    # 合并所有分块
    with open(save_path, "wb") as final_file:
        for i in range(THREAD_COUNT):
            chunk_path = os.path.join(temp_folder, f"part_{i}")
            if os.path.exists(chunk_path):
                with open(chunk_path, "rb") as part_file:
                    shutil.copyfileobj(part_file, final_file)

    shutil.rmtree(temp_folder)
    print("\n服务器文件下载完成！")
    return True

# 单线程备用下载
def single_thread_download(url, save_path):
    try:
        response = requests.get(url, stream=True, timeout=30)
        total_size = int(response.headers.get("content-length", 0))
        downloaded_size = 0

        with open(save_path, "wb") as file:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    file.write(chunk)
                    downloaded_size += len(chunk)
                    progress = (downloaded_size / total_size) * 100 if total_size else 0
                    print(f"\r下载进度: {progress:.2f}%", end="")

        print("\n服务器文件下载完成！")
        return True
    except Exception as e:
        print(f"\n单线程下载失败: {e}")
        return False

# 获取当前目录 & 桌面目录
current_directory = os.getcwd()
desktop = os.path.join(os.path.expanduser("~"), "Desktop")
server_folder = os.path.join(desktop, "server")

# 检查 Java 安装情况
if not check_java():
    a_bat_path = os.path.join(current_directory, "jdk21_installer.bat")
    if os.path.exists(a_bat_path):
        print("没有检测到 Java，正在运行 jdk21_installer.bat 进行安装...")
        subprocess.run([a_bat_path], shell=True)
        if not check_java():
            print("Java 安装失败，请手动安装 Java")
            exit()
    else:
        print("jdk21_installer.bat 文件不存在，请确保它在当前目录")
        exit()

# 查找 .jar 文件
jar_files = [f for f in os.listdir(current_directory) if f.endswith(".jar")]

# 如果没有 .jar 文件，尝试下载
if not jar_files:
    print("当前目录没有 .jar 文件，尝试从 download.txt 下载...")
    download_link = get_download_link()
    if download_link:
        jar_save_path = os.path.join(current_directory, "server.jar")
        if download_server_jar(download_link, jar_save_path):
            jar_files.append("server.jar")
        else:
            print("下载失败，请检查 download.txt 里的链接是否可用")
            exit()
    else:
        print("未找到 .jar 文件，也无法下载")
        exit()

# 创建 server 文件夹（如果不存在）
if not os.path.exists(server_folder):
    os.makedirs(server_folder)

# 移动 .jar 文件
for jar_file in jar_files:
    jar_file_path = os.path.join(current_directory, jar_file)
    server_jar_path = os.path.join(server_folder, "server.jar")
    shutil.move(jar_file_path, server_jar_path)
    print(f"{jar_file} 已移动并重命名为 server.jar")

# 处理 open.bat 文件
bat_file = "open.bat"
bat_file_path = os.path.join(current_directory, bat_file)
if os.path.exists(bat_file_path):
    shutil.move(bat_file_path, server_folder)
else:
    print("open.bat 文件不存在，请确保它在当前目录")

# 运行 open.bat
bat_file_to_run = os.path.join(server_folder, "open.bat")
if os.path.exists(bat_file_to_run):
    print("启动服务器...")
    process = subprocess.Popen([bat_file_to_run], shell=True)
    process.communicate()
else:
    print("open.bat 文件不存在，无法启动服务器")
    exit()

# 监测 open.bat 执行状态
while os.path.exists(bat_file_to_run):
    print("服务器正在运行，等待 3 秒后重新检测...")
    time.sleep(3)

print("服务器关闭，开始检查 eula.txt")

# 修改 eula.txt
eula_file_path = os.path.join(server_folder, "eula.txt")
if os.path.exists(eula_file_path):
    with open(eula_file_path, 'r') as file:
        eula_content = file.read()

    if "eula=false" in eula_content:
        eula_content = eula_content.replace("eula=false", "eula=true")
        with open(eula_file_path, 'w') as file:
            file.write(eula_content)
        print("eula.txt 已更新为 eula=true")
    else:
        print("eula.txt 已设置为 eula=true，无需修改")
else:
    print("没有找到 eula.txt 文件")

print("服务器配置完成！")
time.sleep(3)
input("按 任意 键退出...")